import json
import requests

from odoo import api, fields, models
from odoo.exceptions import ValidationError
from datetime import datetime, timedelta
from ..tools import sign_tools


class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    app_id = fields.Char('APP ID', default='00000000000000000000000000000000')
    app_secret = fields.Char('APP验证Secret', default='xxxxxxxxxxxxxxxx')
    app_redirect_uri = fields.Char('APP授权回调地址', default='http://localhost:8070/ro/api/gjp/get_token/v1')
    app_access_token = fields.Char('token', readonly=True)
    app_refresh_token = fields.Char('Refresh Token', readonly=True)
    app_sign_key = fields.Char('Sign Key')
    app_env_selection = fields.Selection([('test', '测试环境'), ('online', '线上环境')], string='请求环境类型', default='test')
    app_expires_in = fields.Char('Token过期时间', readonly=True)
    app_re_expires_in = fields.Char('Refresh Token过期时间', readonly=True)

    @api.model
    def get_values(self):
        res = super(ResConfigSettings, self).get_values()
        ir_config = self.env['ir.config_parameter'].sudo()

        app_id = ir_config.get_param('ro_base_api.app_id')
        app_secret = ir_config.get_param('ro_base_api.app_secret')
        app_redirect_uri = ir_config.get_param('ro_base_api.app_redirect_uri')
        app_access_token = ir_config.get_param('ro_base_api.app_access_token')
        app_refresh_token = ir_config.get_param('ro_base_api.app_refresh_token')
        app_sign_key = ir_config.get_param('ro_base_api.app_sign_key')
        app_env_selection = ir_config.get_param('ro_base_api.app_env_selection')
        app_expires_in = ir_config.get_param('ro_base_api.app_expires_in')
        app_re_expires_in = ir_config.get_param('ro_base_api.app_re_expires_in')

        res.update(
            app_id=app_id,
            app_secret=app_secret,
            app_redirect_uri=app_redirect_uri,
            app_access_token=app_access_token,
            app_refresh_token=app_refresh_token,
            app_sign_key=app_sign_key,
            app_env_selection=app_env_selection,
            app_expires_in=app_expires_in,
            app_re_expires_in=app_re_expires_in,
        )
        return res

    @api.model
    def set_values(self):
        super(ResConfigSettings, self).set_values()
        ir_config = self.env['ir.config_parameter'].sudo()

        ir_config.set_param('ro_base_api.app_id', self.app_id or '')
        ir_config.set_param('ro_base_api.app_secret', self.app_secret or '')
        ir_config.set_param('ro_base_api.app_redirect_uri', self.app_redirect_uri or '')
        ir_config.set_param('ro_base_api.app_access_token', self.app_access_token or '')
        ir_config.set_param('ro_base_api.app_refresh_token', self.app_refresh_token or '')
        ir_config.set_param('ro_base_api.app_sign_key', self.app_sign_key or '')
        ir_config.set_param('ro_base_api.app_env_selection', self.app_env_selection or '')
        ir_config.set_param('ro_base_api.app_expires_in', self.app_expires_in or '')
        ir_config.set_param('ro_base_api.app_re_expires_in', self.app_re_expires_in or '')

        super(ResConfigSettings, self).set_values()

    def button_app_authorize(self):
        ir_config = self.env['ir.config_parameter'].sudo()
        # web_base_url = self.env["ir.config_parameter"].get_param("web.base.url")
        app_id = ir_config.get_param('ro_base_api.app_id')
        app_redirect_uri = ir_config.get_param('ro_base_api.app_redirect_uri')
        app_env_selection = ir_config.get_param('ro_base_api.app_env_selection')

        if app_env_selection == 'test':
            url = 'http://d7.mygjp.com.cn:666/account/login?appkey='
        elif app_env_selection == 'online':
            url = 'https://authcentral.wsgjp.com/account/login?appkey='

        # 构成 授权地址
        new_redirect_uri = url + app_id + '&redirect_url=' + app_redirect_uri + '&keyword=keyword'
        # 跳转到 带参地址
        action = {
            'type': 'ir.actions.act_url',
            'url': new_redirect_uri,
            'target': 'new',
        }
        return action

    def button_refresh_token(self):
        app_key = self.env['ir.config_parameter'].sudo().get_param('ro_base_api.app_id')
        app_secret = self.env['ir.config_parameter'].sudo().get_param('ro_base_api.app_secret')
        app_sign_key = self.env['ir.config_parameter'].sudo().get_param('ro_base_api.app_sign_key')
        app_refresh_token = self.env['ir.config_parameter'].sudo().get_param('ro_base_api.app_refresh_token')
        app_env_selection = self.env['ir.config_parameter'].sudo().get_param('ro_base_api.app_env_selection')
        tool = sign_tools.SignTools()

        # 创建 参数p
        json_param = json.dumps({
            'TimeStamp': (datetime.utcnow() + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'),
            'GrantType': 'refresh_token',
            'AuthParam': app_refresh_token
        }, separators=(',', ':'))
        p = tool.aes_encode(json_param, app_secret, app_secret[5:21])

        # 创建 参数sign
        sign_data = json.dumps({
            'appkey': app_key,
            'p': p,
            'signkey': app_sign_key
        }, separators=(',', ':'))
        sign = tool.sha256_encode(sign_data)

        # 请求链接
        if app_env_selection == 'test':
            post_url = 'http://d7.mygjp.com.cn:8013/api/token'
        elif app_env_selection == 'online':
            post_url = 'http://apigateway.wsgjp.com.cn/api/token'
        # 请求数据
        headers = {'ContentType': 'application/x-www-form-urlencoded;charset=utf-8'}
        post_data = {
            'appkey': app_key,
            'p': p,
            'sign': sign
        }
        try:
            response = requests.post(url=post_url, data=post_data, headers=headers)
        except Exception:
            raise ValidationError('请求失败')
        # 取得 返回值
        content = json.loads(response.content.decode('utf-8'))
        if content['iserror']:
            self.env['ro.api.log'].sudo().create({
                'host': response.request.url,
                'status': response.status_code,
                'path': response.request.path_url,
                'method': response.request.method,
                'type': 'in',
                'message': response.content.decode('utf-8'),
                'body': response.request.body,
                'api_method': '刷新token',
            })
            raise ValidationError(str(content['errorcode']) + ': ' + content['errormessage'])
        else:
            value = json.loads(tool.aes_decode(content['response']['response'], app_secret, app_secret[5:21]))
        # 将刷新的 token 存入系统
        self.env['ir.config_parameter'].sudo().set_param('ro_base_api.app_access_token', value['auth_token'])
        # 将过期时间存入系统
        self.env['ir.config_parameter'].sudo().set_param('ro_base_api.app_expires_in',
                                                            str(datetime.now() + timedelta(hours=8) + timedelta(
                                                                seconds=value['expires_in']))[:19])
        self.env['ir.config_parameter'].sudo().set_param('ro_base_api.app_re_expires_in',
                                                            str(datetime.now() + timedelta(hours=8) + timedelta(
                                                                seconds=value['re_expires_in']))[:19])

        # 记录日志
        self.env['ro.api.log'].sudo().create({
            'host': response.request.url,
            'status': response.status_code,
            'path': response.request.path_url,
            'method': response.request.method,
            'type': 'in',
            'message': response.content.decode('utf-8'),
            'body': response.request.body,
            'api_method': '刷新token',
        })

        return '刷新成功'
